﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.esriSystem;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace Akiha.Core
{
    public class GeometryWrapper
    {
        public static IPolygon PolylineToPolygon(IPolyline ipPline)
        {
            try
            {
                ISegmentCollection ipSegColl;
                IPolygon ipPolygon = new PolygonClass();
                IGeometryCollection ipPolylineToPolygon = new PolygonClass();
                IClone ipClone1, ipClone2;
                ipClone1 = ipPline as IClone;
                ipClone2 = ipClone1.Clone();
                IGeometryCollection ipGeosPolyline = ipClone2 as IGeometryCollection;
                int iCount = ipGeosPolyline.GeometryCount;
                object before = Type.Missing;
                object after = Type.Missing;
                for (int i = 0; i < iCount; i++)
                {
                    IGeometry ipSRing;
                    ipSegColl = new RingClass();
                    ipSRing = ipGeosPolyline.get_Geometry(i);
                    ipSegColl.AddSegmentCollection(ipSRing as ISegmentCollection);
                    IRing ring = ipSegColl as IRing;
                    IGeometry geo = ring;
                    ipPolylineToPolygon.AddGeometry(geo, ref before, ref after);
                    Marshal.ReleaseComObject(ipSRing);
                    Marshal.ReleaseComObject(ring);
                    Marshal.ReleaseComObject(geo);
                }
                ipPolygon = ipPolylineToPolygon as IPolygon;
                ipPolygon.SimplifyPreserveFromTo();
                //Marshal.ReleaseComObject(ipPolylineToPolygon);            
                Marshal.ReleaseComObject(ipClone1);
                Marshal.ReleaseComObject(ipClone2);
                return ipPolygon;
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message);
                return null;
            }
        }

        public static ISegmentCollection MakePath(IPoint point1, IPoint point2)
        {
            ILine line1 = new LineClass() { FromPoint = point1, ToPoint = point2 };
            ISegmentCollection path = new PathClass();
            object Missing1 = Type.Missing;
            object Missing2 = Type.Missing;
            path.AddSegment(line1 as ISegment, ref Missing1, ref Missing2);
            return path;
        }

        public static List<IPoint> GetPoints(IGeometry geometry)
        {
            List<IPoint> Points = new List<IPoint>();
            IPointCollection pointCollection = geometry as IPointCollection;
            for (int i = 0; i < pointCollection.PointCount; i++)
            {
                if (i == pointCollection.PointCount - 1)
                {
                    continue;
                }
                IPoint point = pointCollection.get_Point(i);
                Points.Add(point);
            }
            return Points;
        }


        public static List<IPolyline> GetPolylines(IGeometry geometry)
        {
            List<IPolyline> lines = new List<IPolyline>();
            IPointCollection pointCollection = geometry as IPointCollection;
            for (int i = 0; i < pointCollection.PointCount; i++)
            {
                if (i == pointCollection.PointCount - 1)
                {
                    continue;
                }
                IPoint start_Point = pointCollection.get_Point(i);
                IPoint end_Point = pointCollection.get_Point(i + 1);
                ISegmentCollection path = GeometryWrapper.MakePath(start_Point, end_Point);
                IGeometryCollection polyline = new PolylineClass();
                object obj = Type.Missing;
                polyline.AddGeometry(path as IGeometry, ref obj, ref obj);

                lines.Add(polyline as IPolyline);
            }
            return lines;
        }

        public static IPolyline PointsToPolyline(IPoint FromPoint, IPoint ToPoint)
        {
            ISegmentCollection path = GeometryWrapper.MakePath(FromPoint, ToPoint);
            IGeometryCollection polyline = new PolylineClass();
            object obj = Type.Missing;
            polyline.AddGeometry(path as IGeometry, ref obj, ref obj);

            return polyline as IPolyline;
        }

        public static IPolygon PointsToPolygon(List<IPoint> points)
        {
            IPointCollection polygon = new PolygonClass();
            object obj = Type.Missing;
            points.Add(points[0]);
            for (int i = 0; i < points.Count; i++)
            {
                polygon.AddPoint(points[i], ref obj, ref obj);
            }
            return polygon as IPolygon;
        }

        public static IPolyline PointsToPolyline(List<IPoint> points)
        {
            IPointCollection polyline = new PolylineClass();
            object obj = Type.Missing;
            points.Add(points[0]);
            for (int i = 0; i < points.Count; i++)
            {
                polyline.AddPoint(points[i], ref obj, ref obj);
            }
            return polyline as IPolyline;
        }

        public static IGeometry Transform(IGeometry Geometry, double x, double y)
        {
            if (Geometry == null)
            {
                return null;
            }
            ITransform2D pTransform2D = Geometry as ITransform2D;
            pTransform2D.Move(x, y);
            return Geometry;
        }


    }
}
